package main

import (
	"context"
	"fmt"
	"regexp"
)

type ExecNode struct {
	errNext KeeperNode
	next    KeeperNode
	pre     KeeperNode
	id      string
	ctx     context.Context
	ret     interface{}

	pw       *pwatcher
	procName string
	cmdName  string
	cmdArgs  []string
	judge    string
}

func (p *ExecNode) SetNext(n, e KeeperNode) error {
	p.next = n
	p.errNext = e
	return nil
}

func (p *ExecNode) SetPrevious(n KeeperNode) error {
	p.pre = n
	return nil
}

func (p *ExecNode) Next() (KeeperNode, context.Context) {
	if _, ok := p.ret.(error); ok {
		return p.errNext, p.ctx
	} else {
		return p.next, p.ctx
	}
}

func (p *ExecNode) Meta() map[string]string {
	return map[string]string{"id": p.id}
}

func (p *ExecNode) Finished() bool {
	return p.ret != nil
}

func (p *ExecNode) Result() (interface{}, error) {
	reg, _ := regexp.Compile(p.judge)
	switch t := p.ret.(type) {
	case error:
		return nil, t
	case []string:
		if reg.MatchString(t[len(t)-1]) {
			return t, nil
		} else {
			return nil, fmt.Errorf("judge false")
		}
	case nil:
		return nil, fmt.Errorf("ret nil")
	default:
		return nil, fmt.Errorf("unkonw type")
	}
}

func (p *ExecNode) Do(ctx context.Context) {
	p.ctx = ctx
	ret, err := p.pw.Run(p.procName, p.cmdName, p.cmdArgs)
	if err != nil {
		p.ret = err
	} else {
		p.ret = ret
	}
}
